package com.class06;

import com.class06.ioc01.ClientServiceImpl;
import com.class06.ioc01.HappyComponent;
import com.class06.ioc02.SimpleMovieLister;
import com.class06.ioc02.UserDao;
import com.class06.ioc02.UserService;
import com.class06.ioc04.JavaBean;
import com.class06.ioc04.JavaBean2;
import com.class06.ioc05.JavaBeanFactory;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Map;

public class TestPerson {
//    没有使用spring之前
    @Test
    public void test(){
        Person person = new Person();
        person.setName("张三");
        person.setAge(18);
    }


//    使用spring之后
//    一、编写spring配置文件：可以使用xml、注解、java配置文件三种方式配置
//    1、xml配置文件方式配置，一般把xml文件放在resources目录下
//    2、创建spring的IOC容器
//    3、从容器中获取对象
    @Test
    public void test2(){
//        创建spring的IOC容器并加载配置文件
        ClassPathXmlApplicationContext classPathXmlApplicationContext
                = new ClassPathXmlApplicationContext("spring-test.xml");
//        从容器中获取对象  默认是单例模式
        Person person = (Person) classPathXmlApplicationContext.getBean("person");
        person.setName("李四");
        person.setAge(19);
        Person person1 = (Person) classPathXmlApplicationContext.getBean("person");
        System.out.println(person);
        System.out.println(person1);

    }


    @Test
    public void test3(){
//        创建spring的IOC容器并加载配置文件
        ClassPathXmlApplicationContext classPathXmlApplicationContext
                = new ClassPathXmlApplicationContext("spring-bean-01.xml");
//        HappyComponent happyComponent =
//                (HappyComponent) classPathXmlApplicationContext.getBean("happyComponent");
//        HappyComponent happyComponent1 =(HappyComponent) classPathXmlApplicationContext.getBean("happyComponent");
//        happyComponent.doWork();
////        java  中类型：基本类型  和  引用类型(对比是地址)  相当于地址相同，证明了同一个对象，进而证明了单例模式
//        System.out.println(happyComponent == happyComponent1);

        ClientServiceImpl clientService = (ClientServiceImpl) classPathXmlApplicationContext.getBean("clientService2");


    }

    @Test
    public void test4(){
//        创建spring的IOC容器并加载配置文件
        ClassPathXmlApplicationContext classPathXmlApplicationContext
                = new ClassPathXmlApplicationContext("spring-bean-02.xml");
        UserService userService = (UserService) classPathXmlApplicationContext.getBean("userService");

        UserDao userDao = userService.getUserDao();
        System.out.println(userDao);


        System.out.println("=============================");
//        spring :  创建对象  （ioc控制反转）  、
//        属性赋值   (di) 又分为setter注入和构造器注入（
//        单个参数注入、多个参数注入<分为三种情况：1、通过角标索引、2、通过属性名、3、顺序赋值>）
        SimpleMovieLister simpleMovieLister = (SimpleMovieLister) classPathXmlApplicationContext.getBean("simpleMovieLister");
        System.out.println(simpleMovieLister.getMovieName());
    }


    @Test
    public void test5(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext
                = new ClassPathXmlApplicationContext("spring-bean-04.xml");
        JavaBean javaBean = (JavaBean) classPathXmlApplicationContext.getBean("javaBean");
        JavaBean javaBean1 = (JavaBean) classPathXmlApplicationContext.getBean("javaBean");
        System.out.println(javaBean==javaBean1);  // true  证明了单例模式
//        关闭容器时，会执行销毁方法
        JavaBean2 javaBean2 = (JavaBean2)
                classPathXmlApplicationContext.getBean("javaBean2");
        JavaBean2 javaBean3 = (JavaBean2)
                classPathXmlApplicationContext.getBean("javaBean2");
        System.out.println(javaBean2==javaBean3); // false  证明了多例模式
        Map<String, JavaBean2> beansOfType = classPathXmlApplicationContext.getBeansOfType(JavaBean2.class);
        beansOfType.forEach((k,v)->{
            System.out.println(k+"-->"+v);
        });



        classPathXmlApplicationContext.close();

    }

    @Test
    public void test6(){

        ApplicationContext iocContainer = new ClassPathXmlApplicationContext("spring-bean-05.xml");

        //注意: 直接根据声明FactoryBean的id,获取的是getObject方法返回的对象
//        JavaBean javaBean = iocContainer.getBean("javaBean",JavaBean.class);
//        System.out.println("javaBean = " + javaBean);

        //如果想要获取FactoryBean对象, 直接在id前添加&符号即可!  &happyMachine7 这是一种固定的约束
        Object bean = iocContainer.getBean("&javaBean");
        System.out.println("bean = " + bean);


    }
}
